from ipmininet.iptopo import IPTopo
from ipmininet.ipnet import IPNet
from ipmininet.cli import IPCLI
import os
import time


class MyTopology(IPTopo):

    def build(self, *args, **kwargs):
        c1 = self.addHost("c1", use_v4=False)

        h1 = self.addHost("h1", use_v4=False)
        r1 = self.addHost("r1", use_v4=False)

        r2 = self.addHost("r2", use_v4=False)
        h2 = self.addHost("h2", use_v4=False)

        r3 = self.addHost("r3", use_v4=False)
        h3 = self.addHost("h3", use_v4=False)

        c1r1 = self.addLink(c1, r1)
        c1r1[c1].addParams(ip="fd01::11:1/112")
        c1r1[r1].addParams(ip="fd01::11:2/112")

        h1r1 = self.addLink(h1, r1)
        h1r1[h1].addParams(ip="fd00::11:1/112")
        h1r1[r1].addParams(ip="fd00::11:2/112")

        r1r2 = self.addLink(r1, r2)
        r1r2[r1].addParams(ip="fd00::12:1/112")
        r1r2[r2].addParams(ip="fd00::12:2/112")

        r2h2 = self.addLink(r2, h2)
        r2h2[h2].addParams(ip="fd00::22:1/112")
        r2h2[r2].addParams(ip="fd00::22:2/112")

        r2r3 = self.addLink(r2, r3)
        r2r3[r2].addParams(ip="fd00::23:1/112")
        r2r3[r3].addParams(ip="fd00::23:2/112")

        r3h3 = self.addLink(r3, h3)
        r3h3[h3].addParams(ip="fd00::33:1/112")
        r3h3[r3].addParams(ip="fd00::33:2/112")

        super().build(*args, **kwargs)

def close():
    try:
        os.remove('./if_name_to_ipv6')
        os.remove('./nohup.out')
    finally:
        pass

if __name__ == '__main__':
    net = IPNet(topo=MyTopology())
    net['c1'].cmd('ip -6 r add default via fd01::11:2')
    net['c1'].cmd('ethtool -K c1-eth0 tx off')

    net['h1'].cmd('ip -6 r add default via fd00::11:2')
    net['h1'].cmd('ethtool -K h1-eth0 tx off')
    #
    net['h2'].cmd('ip -6 r add default via fd00::22:2')
    net['h2'].cmd('ethtool -K h2-eth0 tx off')

    net['h3'].cmd('ip -6 r add default via fd00::33:2')
    net['h3'].cmd('ethtool -K h3-eth0 tx off')

    net['r1'].cmd('sysctl -w net.ipv6.conf.all.forwarding=1')
    net['r1'].cmd('ethtool -K r1-eth0 tx off')
    net['r1'].cmd('ethtool -K r1-eth1 tx off')
    net['r1'].cmd('ethtool -K r1-eth2 tx off')

    net['r2'].cmd('sysctl -w net.ipv6.conf.all.forwarding=1')
    net['r2'].cmd('ethtool -K r2-eth0 tx off')
    net['r2'].cmd('ethtool -K r2-eth1 tx off')

    net['r3'].cmd('sysctl -w net.ipv6.conf.all.forwarding=1')
    net['r3'].cmd('ethtool -K r3-eth0 tx off')
    net['r3'].cmd('ethtool -K r3-eth1 tx off')

    net['r1'].cmd('nohup ./qiao &')
    net['r2'].cmd('nohup ./qiao &')
    net['r3'].cmd('nohup ./qiao &')

    time.sleep(5)
    net['h1'].cmd('nohup etcd --name h1 \
                      --initial-advertise-peer-urls http://[fd00::11:1]:2380 \
                      --listen-peer-urls http://[fd00::11:1]:2380 \
                      --listen-client-urls http://[fd00::11:1]:2379 \
                      --advertise-client-urls http://[fd00::11:1]:2379 \
                      --initial-cluster h1=http://[fd00::11:1]:2380,h2=http://[fd00::22:1]:2380,h3=http://[fd00::33:1]:2380 \
                      --initial-cluster-token my-etcd-token \
                      --initial-cluster-state new \
                      --data-dir ./etcd/h1 &')

    net['h2'].cmd('nohup etcd --name h2 \
                      --initial-advertise-peer-urls http://[fd00::22:1]:2380 \
                      --listen-peer-urls http://[fd00::22:1]:2380 \
                      --listen-client-urls http://[fd00::22:1]:2379 \
                      --advertise-client-urls http://[fd00::22:1]:2379 \
                      --initial-cluster h1=http://[fd00::11:1]:2380,h2=http://[fd00::22:1]:2380,h3=http://[fd00::33:1]:2380 \
                      --initial-cluster-token my-etcd-token \
                      --initial-cluster-state new \
                      --data-dir ./etcd/h2 &')

    net['h3'].cmd('nohup etcd --name h3 \
                      --initial-advertise-peer-urls http://[fd00::33:1]:2380 \
                      --listen-peer-urls http://[fd00::33:1]:2380 \
                      --listen-client-urls http://[fd00::33:1]:2379 \
                      --advertise-client-urls http://[fd00::33:1]:2379 \
                      --initial-cluster h1=http://[fd00::11:1]:2380,h2=http://[fd00::22:1]:2380,h3=http://[fd00::33:1]:2380 \
                      --initial-cluster-token my-etcd-token \
                      --initial-cluster-state new \
                      --data-dir ./etcd/h3 &')

    net['c1'].cmd('export ETCDCTL_API=3')
    net['c1'].cmd('export ETCDCTL_ENDPOINTS=http://[fd00::11:1]:2379,http://[fd00::22:1]:2379,http://[fd00::33:1]:2379')

    try:
        net.start()
        IPCLI(net)
    finally:
        net.stop()
        close()